﻿// Copyright 2009-2024 Josh Close
// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
// https://github.com/JoshClose/CsvHelper
using CsvHelper.Configuration;
using CsvHelper.TypeConversion;

namespace CsvHelper;

/// <summary>
/// Defines methods used to write a CSV row.
/// </summary>
public interface IWriterRow
{
	/// <summary>
	/// The header record.
	/// </summary>
	string?[]? HeaderRecord { get; }

	/// <summary>
	/// The current row.
	/// </summary>
	int Row { get; }

	/// <summary>
	/// The current field index.
	/// </summary>
	int Index { get; }

	/// <summary>
	/// Gets the writing context.
	/// </summary>
	CsvContext Context { get; }

	/// <summary>
	/// Gets or sets the configuration.
	/// </summary>
	IWriterConfiguration Configuration { get; }

	/// <summary>
	/// Writes a field that has already been converted to a
	/// <see cref="string"/> from an <see cref="ITypeConverter"/>.
	/// If the field is null, it won't get written. A type converter 
	/// will always return a string, even if field is null. If the 
	/// converter returns a null, it means that the converter has already
	/// written data, and the returned value should not be written.
	/// </summary>
	/// <param name="field">The converted field to write.</param>
	/// <param name="fieldType">The type of the field before it was converted into a string.</param>
	void WriteConvertedField(string? field, Type fieldType);

	/// <summary>
	/// Writes the field to the CSV file. The field
	/// may get quotes added to it.
	/// When all fields are written for a record,
	/// <see cref="IWriter.NextRecord()" /> must be called
	/// to complete writing of the current record.
	/// </summary>
	/// <param name="field">The field to write.</param>
	void WriteField(string? field);

	/// <summary>
	/// Writes the field to the CSV file. This will
	/// ignore any need to quote and ignore
	/// <see cref="CsvHelper.Configuration.CsvConfiguration.ShouldQuote"/>
	/// and just quote based on the shouldQuote
	/// parameter.
	/// When all fields are written for a record,
	/// <see cref="IWriter.NextRecord()" /> must be called
	/// to complete writing of the current record.
	/// </summary>
	/// <param name="field">The field to write.</param>
	/// <param name="shouldQuote">True to quote the field, otherwise false.</param>
	void WriteField(string? field, bool shouldQuote);

	/// <summary>
	/// Writes the field to the CSV file.
	/// When all fields are written for a record,
	/// <see cref="IWriter.NextRecord()" /> must be called
	/// to complete writing of the current record.
	/// </summary>
	/// <typeparam name="T">The type of the field.</typeparam>
	/// <param name="field">The field to write.</param>
	void WriteField<T>(T? field);

	/// <summary>
	/// Writes the field to the CSV file.
	/// When all fields are written for a record,
	/// <see cref="IWriter.NextRecord" /> must be called
	/// to complete writing of the current record.
	/// </summary>
	/// <typeparam name="T">The type of the field.</typeparam>
	/// <param name="field">The field to write.</param>
	/// <param name="converter">The converter used to convert the field into a string.</param>
	void WriteField<T>(T? field, ITypeConverter converter);

	/// <summary>
	/// Writes the field to the CSV file
	/// using the given <see cref="ITypeConverter"/>.
	/// When all fields are written for a record,
	/// <see cref="IWriter.NextRecord()" /> must be called
	/// to complete writing of the current record.
	/// </summary>
	/// <typeparam name="T">The type of the field.</typeparam>
	/// <typeparam name="TConverter">The type of the converter.</typeparam>
	/// <param name="field">The field to write.</param>
	void WriteField<T, TConverter>(T? field);

	/// <summary>
	/// Writes a comment.
	/// </summary>
	/// <param name="comment">The comment to write.</param>
	void WriteComment(string? comment);

	/// <summary>
	/// Writes the header record from the given members.
	/// </summary>
	/// <typeparam name="T">The type of the record.</typeparam>
	void WriteHeader<T>();

	/// <summary>
	/// Writes the header record from the given members.
	/// </summary>
	/// <param name="type">The type of the record.</param>
	void WriteHeader(Type type);

	/// <summary>
	/// Writes the record to the CSV file.
	/// </summary>
	/// <typeparam name="T">The type of the record.</typeparam>
	/// <param name="record">The record to write.</param>
	void WriteRecord<T>(T record);
}
